using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Data;
using System.Net.Mail;

using BPCSFileDaemon.FileFactory;

using Kypris2.Utils;
using Kypris2.CoreElements;
using Kypris2.CoreManagers;

using Jamila2.Database;
using GonzalesCore.CoreElements;
using GonzalesCore.CoreManagers;

namespace BPCSFileDaemon
{
    public class FileDaemon
    {
        protected string ArchievedPath = "", LogPath = "", SourcePath = "";
        protected string DatabaseConnection = "";
        protected TypeOfDatabase DatabaseType = TypeOfDatabase.MSSQL;
        public ArrayList LoggedMessages = new ArrayList();
        protected bool EmailActvie = false;
        protected string SMTP = "";
        protected PersonalSessionAccount CurrentSystemSession = null;


        public FileDaemon(DaemonConfigurator CurConfigurator)
        {
            this.ArchievedPath = CurConfigurator.PathForArchievedFiles;
            this.LogPath = CurConfigurator.PathForLogFiles;
            this.SourcePath = CurConfigurator.PathForSourceFiles;
            this.DatabaseConnection = CurConfigurator.DatabaseConnection;
            this.DatabaseType = CurConfigurator.DatabaseType;
            this.EmailActvie = CurConfigurator.Email_Active;
            this.SMTP = CurConfigurator.SMTP;

            this.CurrentSystemSession = new PersonalSessionAccount(null, this.DatabaseType, this.DatabaseConnection);

        }

        public bool StartWatching()
        {
            bool smooth = true;

            DirectoryInfo FolderObj = new DirectoryInfo(this.SourcePath);

            FileInfo[] FilesListing = FolderObj.GetFiles();

            string FileName = "";

            foreach (FileInfo CurFileInfo in FilesListing)
            {
                FileName = CurFileInfo.Name;

                if (FileName.IndexOf("WECLAIM") == 0)
                {
                    // exchange rate file need to handle handle differently from other files due to file naming convention
                    if (FileName.CompareTo("WECLAIMR.WECLAIMR") == 0)
                    {
                        #region Exchange Rate File
                        using (ExRateFileFactory CurFileFactory = new ExRateFileFactory(CurFileInfo.FullName, this.DatabaseConnection, this.DatabaseType))
                        {
                            LoggedMessages.Add(DateTime.Today.ToShortDateString() + " " + DateTime.Today.ToShortTimeString() + " " + "*** Exchange Rate extract ***");
                            if (CurFileFactory.ReadFile())
                            {
                                LoggedMessages.Add(DateTime.Today.ToShortDateString() + " " + DateTime.Today.ToShortTimeString() + " " + "File extracted successfully.");
                            }
                            else
                            {
                                LoggedMessages.Add(DateTime.Today.ToShortDateString() + " " + DateTime.Today.ToShortTimeString() + " " + "Error: " + CurFileFactory.ErrorMessage);
                            }
                        }

                        #endregion
                    }
                    else
                    {
                        #region Non-Exchange Rate File

                        FileName = FileName.Substring(0, FileName.IndexOf("."));
                        if (FileName.IndexOf("WECLAIM") == 0)
                        {
                            string FileType = FileName.Substring(7, 1);
                            string Entity = FileName.Substring(8, 2);

                            #region Analyze File

                            switch (FileType)
                            {
                                case "E":   // employee

                                    using (EmployeeFileFactory CurFileFactory = new EmployeeFileFactory(CurFileInfo.FullName, this.DatabaseConnection, this.DatabaseType, Entity))
                                    {
                                        LoggedMessages.Add(DateTime.Today.ToShortDateString() + " " + DateTime.Today.ToShortTimeString() + " " + "*** Employees extract (" + Entity + ") ***");
                                        if (CurFileFactory.ReadFile())
                                        {
                                            LoggedMessages.Add(DateTime.Today.ToShortDateString() + " " + DateTime.Today.ToShortTimeString() + " " + "File extracted successfully.");
                                        }
                                        else
                                        {
                                            LoggedMessages.Add(DateTime.Today.ToShortDateString() + " " + DateTime.Today.ToShortTimeString() + " " + "Error: " + CurFileFactory.ErrorMessage);
                                        }
                                    }
                                    break;

                                case "P": // project
                                    using (ProjectFileFactory CurFileFactory = new ProjectFileFactory(CurFileInfo.FullName, this.DatabaseConnection, this.DatabaseType))
                                    {
                                        LoggedMessages.Add(DateTime.Today.ToShortDateString() + " " + DateTime.Today.ToShortTimeString() + " " + "*** Projects extract (" + Entity + ") ***");
                                        if (CurFileFactory.ReadFile())
                                        {
                                            LoggedMessages.Add(DateTime.Today.ToShortDateString() + " " + DateTime.Today.ToShortTimeString() + " " + "File extracted successfully.");
                                        }
                                        else
                                        {
                                            LoggedMessages.Add(DateTime.Today.ToShortDateString() + " " + DateTime.Today.ToShortTimeString() + " " + "Error: " + CurFileFactory.ErrorMessage);
                                        }
                                    }
                                    break;

                                case "A": // expense details
                                    // expense detail currently only acept SG file only
                                    if (Entity.CompareTo("SG") == 0)
                                    {
                                        using (ExpenseDetailFactory CurFileFactory = new ExpenseDetailFactory(CurFileInfo.FullName, this.DatabaseConnection, this.DatabaseType))
                                        {
                                            LoggedMessages.Add(DateTime.Today.ToShortDateString() + " " + DateTime.Today.ToShortTimeString() + " " + "*** Expense Detail extract (" + Entity + ") ***");
                                            if (CurFileFactory.ReadFile())
                                            {
                                                LoggedMessages.Add(DateTime.Today.ToShortDateString() + " " + DateTime.Today.ToShortTimeString() + " " + "File extracted successfully.");
                                            }
                                            else
                                            {
                                                LoggedMessages.Add(DateTime.Today.ToShortDateString() + " " + DateTime.Today.ToShortTimeString() + " " + "Error: " + CurFileFactory.ErrorMessage);
                                            }
                                        }
                                    }
                                    break;

                                case "C": // CRMOD 
                                    using (CRMODFileFactory CurFileFactory = new CRMODFileFactory(CurFileInfo.FullName, this.DatabaseConnection, this.DatabaseType))
                                    {
                                        LoggedMessages.Add(DateTime.Today.ToShortDateString() + " " + DateTime.Today.ToShortTimeString() + " " + "*** CRMOD extract (" + Entity + ") ***");
                                        if (CurFileFactory.ReadFile())
                                        {
                                            LoggedMessages.Add(DateTime.Today.ToShortDateString() + " " + DateTime.Today.ToShortTimeString() + " " + "File extracted successfully.");
                                        }
                                        else
                                        {
                                            LoggedMessages.Add(DateTime.Today.ToShortDateString() + " " + DateTime.Today.ToShortTimeString() + " " + "Error: " + CurFileFactory.ErrorMessage);
                                        }
                                    }
                                    break;
                            }

                            #endregion
                        }

                        #endregion
                    }

                    #region Move file
                    try
                    {
                        string NewFolderName = DateTime.Now.Month + "-" + DateTime.Now.Day + "-" + DateTime.Now.Year;

                        if (!Directory.Exists(this.ArchievedPath + "\\" + NewFolderName))
                            Directory.CreateDirectory(this.ArchievedPath + "\\" + NewFolderName);

                        File.Move(this.SourcePath + "\\" + CurFileInfo.Name, this.ArchievedPath + "\\" + NewFolderName + "\\" + CurFileInfo.Name + "-" + "-" + DateTime.Now.Hour + "-" + DateTime.Now.Minute);
                    }
                    catch (Exception ex)
                    {
                        smooth = false;
                        LoggedMessages.Add(DateTime.Today.ToShortDateString() + " " + DateTime.Today.ToShortTimeString() + " " + " File moving : Exception : " + ex.Message);
                    }
                    #endregion

                }
            }

            //Check the master users table if there's empty email and empty ad distinguished name send email to super admin
            UserManager curManager = new UserManager(this.CurrentSystemSession);
            DataTable dtMasterUsers = curManager.GetUsersWithoutEmailAndADDistinguishedName();
            string MailContent = "", MailTitle = "";

            if (dtMasterUsers != null && dtMasterUsers.Rows.Count > 0)
            {
                #region generate content and send email to Person in charge
                if (this.EmailActvie)
                {
                    MailTitle = "Claimants without Email or AD Distinguished Name in Ezyclaim";
                    MailContent += "<table><tr><td>Employee Name</td><td>Employee ID</td></tr>";

                    for(int i =0; i < dtMasterUsers.Rows.Count; i++)
                    {
                        MailContent += "<tr><td>" + dtMasterUsers.Rows[i][2].ToString() + "</td><td>" + dtMasterUsers.Rows[i][1].ToString() + "</td></tr>";
                    }
                    MailContent += "</table>";

                    if (MailContent.Length > 0)
                    {
                        SystemUsers curAdmin = null;

                        using (UserManager CurUserManager = new UserManager(this.CurrentSystemSession))
                        {
                            curAdmin = CurUserManager.GetAdminPanel();

                            if (curAdmin != null && curAdmin.Count > 0)
                            {
                                for (int x = 0; x < curAdmin.Count; x++)
                                {
                                    using (EmailFactory CurEmailFactory = new EmailFactory(
                                        curAdmin[x].DisplayName,
                                        curAdmin[x].Email,
                                        MailTitle,
                                        MailContent, this.SMTP))
                                     {
                                        if (CurEmailFactory.IsReady)
                                        {
                                            if (!CurEmailFactory.SendNow())
                                            {
                                                LoggedMessages.Add(DateTime.Today.ToShortDateString() + " " + DateTime.Today.ToShortTimeString() + " " + " Sending Email(Missing info) : Exception : " + CurEmailFactory.ErrorMessage);
                                            }
                                            else
                                            {
                                                LoggedMessages.Add(DateTime.Today.ToShortDateString() + " " + DateTime.Today.ToShortTimeString() + " " + " Sending Email(Missing info) : Email sent to " + curAdmin[x].Email);
                                            }
                                        }
                                        else
                                        {
                                            LoggedMessages.Add(DateTime.Today.ToShortDateString() + " " + DateTime.Today.ToShortTimeString() + " " + " Sending Email(Missing info) : Exception : " + CurEmailFactory.ErrorMessage);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                #endregion
            }

            GenerateClaimReminder();

            GenerateCreditCardReminder();

            return smooth;
        }

        #region GenerateCreditCardReminder

        public bool GenerateCreditCardReminder()
        {
            bool smooth = true;

            using (CompanyManager CurCompanyManager = new CompanyManager(this.CurrentSystemSession))
            {
                GonzalesCompanies CompanyCollection = CurCompanyManager.GetAllCompany();

                if (CompanyCollection != null)
                {
                    LoggedMessages.Add("*** ECLAIMCREDITCARDREMINDER ***");

                    for (int z = 0; z < CompanyCollection.Count; z++)
                    {
                        int CreditCardReminder = Convert.ToInt32(CompanyCollection[z].CreditCardReminder);

                        if (CreditCardReminder > 0)
                        {
                            GonzalesCompany curCompany = new GonzalesCompany(CompanyCollection[z].InternalID, CompanyCollection[z].CompanyName);
                            CreditCardManager CurCreditCardManager = new CreditCardManager(this.CurrentSystemSession);
                            DataTable CreditCardCollection = CurCreditCardManager.GetAvailableCreditCardItemByCompany(CompanyCollection[z].InternalID, false);

                            try
                            {
                                if (CreditCardCollection.Rows.Count > 0)
                                {
                                    LoggedMessages.Add("Extract the Credit Card Item based on Company");

                                    for (int x = 0; x < CreditCardCollection.Rows.Count; x++)
                                    {
                                        DateTime Transaction_Date = Convert.ToDateTime(CreditCardCollection.Rows[x]["trans_Date"]).AddDays(CreditCardReminder);

                                        if (Transaction_Date <= DateTime.Now)
                                        {
                                            #region Generate Email to approver and user.

                                            #endregion
                                        }

                                    }

                                }
                                else
                                {
                                    LoggedMessages.Add("File Failed for " + CompanyCollection[z].Entity.InternalID + CompanyCollection[z].CompanyCode + " : " + CurCreditCardManager.ErrorMessage);
                                }
                            }
                            catch (Exception ex)
                            {
                                LoggedMessages.Add("File Failed for " + CompanyCollection[z].Entity.InternalID + CompanyCollection[z].CompanyCode + " : Exception : " + ex.Message);
                            }
                        }
                    }
                }
            }

            return smooth;
        }

        #endregion

        #region GenerateClaimReminder

        public bool GenerateClaimReminder()
        {
            bool smooth = true;

            using (CompanyManager CurCompanyManager = new CompanyManager(this.CurrentSystemSession))
            {
                GonzalesCompanies CompanyCollection = CurCompanyManager.GetAllCompany();

                if (CompanyCollection != null)
                {
                    LoggedMessages.Add("*** ECLAIMCLAIMREMINDER ***");

                    for (int z = 0; z < CompanyCollection.Count; z++)
                    {
                        int ClaimReminder = Convert.ToInt32(CompanyCollection[z].ClaimReminder);

                        GonzalesCompany curCompany = new GonzalesCompany(CompanyCollection[z].InternalID, CompanyCollection[z].CompanyName);
                        ClaimManager CurClaimManager = new ClaimManager(this.CurrentSystemSession);
                        ClaimHeaders ClaimCollection = CurClaimManager.GetClaimByStatus(GonzalesClaimHeader.TypeOfClaimStatus.Submitted, curCompany);

                        if (ClaimReminder > 0)
                        {
                            try
                            {

                                if (ClaimCollection != null)
                                {
                                    LoggedMessages.Add("Extract the Claim based on Company");

                                    for (int x = 0; x < ClaimCollection.Count; x++)
                                    {

                                        if (ClaimCollection[x].SubmittedOn.AddDays(ClaimReminder) <= (DateTime.Now) && ClaimCollection[x].ClaimID.Length > 0)
                                        {
                                            #region Generate Email to approver and user.
                                            TimeSpan datediff = DateTime.Now.Subtract(ClaimCollection[x].SubmittedOn);
                                            string MailContent = "", MailTitle = "";

                                            if (this.EmailActvie)
                                            {
                                                #region generate content and send email to Approver
                                                using (EmailGenerator CurMailGenerator = new EmailGenerator(Path.GetFullPath("MailContent\\") + "ReminderClaimForApprover", "en"))
                                                {
                                                    MailContent = CurMailGenerator.GenerateReminderClaimForApprover(ClaimCollection[x].ClaimID, datediff.Days.ToString());

                                                    MailTitle = CurMailGenerator.MailTitle;
                                                }

                                                if (MailContent.Length > 0)
                                                {
                                                    using (EmailFactory CurEmailFactory = new EmailFactory(
                                                        ClaimCollection[x].NextApprover.DisplayName,
                                                        ClaimCollection[x].NextApprover.Email,
                                                        MailTitle,
                                                        MailContent, this.SMTP))
                                                    {
                                                        if (CurEmailFactory.IsReady)
                                                        {
                                                            if (!CurEmailFactory.SendNow())
                                                            {
                                                                LoggedMessages.Add(DateTime.Today.ToShortDateString() + " " + DateTime.Today.ToShortTimeString() + " " + " Sending Email(reminder to approval) : Exception : " + CurEmailFactory.ErrorMessage);
                                                            }
                                                            else
                                                            {
                                                                LoggedMessages.Add(DateTime.Today.ToShortDateString() + " " + DateTime.Today.ToShortTimeString() + " " + " Sending Email(reminder to approval) : Email sent to " + ClaimCollection[x].NextApprover.Email);
                                                            }
                                                        }
                                                        else
                                                        {
                                                            LoggedMessages.Add(DateTime.Today.ToShortDateString() + " " + DateTime.Today.ToShortTimeString() + " " + " Sending Email(reminder to approval) : Exception : " + CurEmailFactory.ErrorMessage);
                                                        }
                                                    }
                                                }
                                                #endregion

                                                #region generate content and send email to claimant
                                                using (EmailGenerator CurMailGenerator = new EmailGenerator(Path.GetFullPath("MailContent\\") + "ReminderClaimForClaimant", "en"))
                                                {
                                                    MailContent = CurMailGenerator.GenerateReminderClaimForClaimant(ClaimCollection[x].ClaimID, datediff.Days.ToString());

                                                    MailTitle = CurMailGenerator.MailTitle;
                                                }

                                                if (MailContent.Length > 0)
                                                {
                                                    using (EmailFactory CurEmailFactory = new EmailFactory(
                                                        ClaimCollection[x].ClaimedBy.DisplayName,
                                                        ClaimCollection[x].ClaimedBy.Email,
                                                        MailTitle,
                                                        MailContent, this.SMTP))
                                                    {
                                                        if (CurEmailFactory.IsReady)
                                                        {
                                                            if (!CurEmailFactory.SendNow())
                                                            {
                                                                LoggedMessages.Add(DateTime.Today.ToShortDateString() + " " + DateTime.Today.ToShortTimeString() + " " + " Sending Email(reminder to claimant) : Exception : " + CurEmailFactory.ErrorMessage);
                                                            }
                                                            else
                                                            {
                                                                LoggedMessages.Add(DateTime.Today.ToShortDateString() + " " + DateTime.Today.ToShortTimeString() + " " + " Sending Email(reminder to claimant) : Email sent to " + ClaimCollection[x].ClaimedBy.Email);
                                                            }
                                                        }
                                                        else
                                                        {
                                                            LoggedMessages.Add(DateTime.Today.ToShortDateString() + " " + DateTime.Today.ToShortTimeString() + " " + " Sending Email(reminder to claimant) : Exception : " + CurEmailFactory.ErrorMessage);
                                                        }
                                                    }
                                                }
                                                #endregion
                                            }
                                            #endregion
                                        }

                                    }

                                }
                                else
                                {
                                    LoggedMessages.Add("File Failed for " + CompanyCollection[z].Entity.InternalID + CompanyCollection[z].CompanyCode + " : " + CurClaimManager.ErrorMessage);
                                }
                            }
                            catch (Exception ex)
                            {
                                LoggedMessages.Add("File Failed for " + CompanyCollection[z].Entity.InternalID + CompanyCollection[z].CompanyCode + " : Exception : " + ex.Message);
                            }
                        }
                    }
                }
            }

            return smooth;
        }

        #endregion


    }
}
